package indexer;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.annolab.tt4j.TreeTaggerException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;

import utils.Constantes;

public class Document {
	private final File fichier;
	private final HashMap<Term, Integer> frequences;
	private final String nom;
	private Integer idBd;
	private int longueur;

	public Document(String fileName) throws IOException {
		// On initialise les variables
		this.nom = fileName;
		this.fichier = new File(Constantes.DOCS_PATH + this.nom);
		this.frequences = new HashMap();
		this.idBd = null;
		this.longueur = 0;

		// On extrait tous les termes utilisés dans le document
		this.extractTerms();
	}

	public HashMap<Term, Integer> getFrequences() {
		return this.frequences;
	}

	public String getNom() {
		return this.nom;
	}

	public Integer getIdBd() {
		return this.idBd;
	}

	public void setIdBd(int idBd) {
		if (idBd > 0) {
			this.idBd = idBd;
		} else {
			throw new IllegalArgumentException("Le paramètre doit être un entier strictement positif.");
		}
	}

	public int getLongueur() {
		return this.longueur;
	}

	private void extractTerms() throws IOException {
		// On parse le fichier
		org.jsoup.nodes.Document document = Jsoup.parse(this.fichier, "UTF-8");

		// On recupère le texte contenu dans le body
		Element body = document.body();

		// On supprime ou remplace les caractères spéciaux du body
		String contenu = this.replaceSpecialCharacters(body.text());

		// On extrait les termes du contenu
		this.constructTerms(contenu);
	}

	private String replaceSpecialCharacters(String texte) {
		texte = texte.replace('.', ' ');
		texte = texte.replace('/', ' ');
		texte = texte.replace('!', ' ');
		texte = texte.replace(';', ' ');
		texte = texte.replace(',', ' ');
		texte = texte.replace('+', ' ');
		texte = texte.replace('*', ' ');
		texte = texte.replace('-', ' ');
		texte = texte.replace('?', ' ');
		texte = texte.replace('[', ' ');
		texte = texte.replace(']', ' ');
		texte = texte.replace('(', ' ');
		texte = texte.replace(')', ' ');
		texte = texte.replace('\'', ' ');
		texte = texte.replace('\"', ' ');
		texte = texte.replace(':', ' ');
		texte = texte.replace('\\', ' ');
		texte = texte.replace('}', ' ');
		texte = texte.replace('{', ' ');
		texte = texte.replace('&', ' ');
		texte = texte.replace('©', ' ');
		texte = texte.replace('|', ' ');

		return texte;
	}

	private void constructTerms(String texte) {
		// on passe en minuscule
		texte = texte.toLowerCase();

		String[] mots = texte.split(" ");

		Pattern pattern = Pattern.compile("^[0-9a-zA-ZÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ_-]{2,}$");

		for (String mot : mots) {
			String motTrimed = mot.trim();

			// On ne prends en compte qu les mots qui ne sont pas dans la stop list
			Matcher matcher = pattern.matcher(motTrimed);

			try {
				if (!Constantes.getStopWords().contains(motTrimed) && matcher.find()) {
					// On récupère le terme de la liste générale des termes
					Term terme = ListeTermes.getInstance().get(motTrimed);

					// On incrémente la fréquence d'apparition de ce terme
					Integer freq = this.frequences.get(terme);

					if (freq == null) {
						freq = 0;

						// si la fréquence retournée est nulle, le terme n'a jamais été ajouté
						// on lui indique donc le document auquel il se lie
						terme.addDocument(this);
					}

					this.frequences.put(terme, freq + 1);
					this.longueur += freq + 1;
				}
			} catch (IOException | TreeTaggerException e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public String toString() {
		return this.nom;
	}
}
